package com.fingard.dsp.bank.directbank.citic42;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;

/**
 * @author dicke
 * @date 2018/3/14 16:08
 */
public class CITIC42BatPayRec extends CITIC42Base implements IBatPayRec {
    //操作成功
    private static final String OPERATESUCCESS = "11";
    //交易应答码为 AAAAAAA 时再判断“交易状态”以确认交易实际状态，不为 AAAAAAA 时，交易为失败状态，无需再判断“交易状态”
    private static final String TRANSRESPONSECODE = "AAAAAAA";

    /**
     * 批量代扣
     * @param p_reqBat
     * @return
     * @throws Exception
     */
    public RetAtsBatPayRec d_BatPayRec(ReqBatPayRec p_reqBat) throws Exception{
        //返回ATS的对象
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_reqBat.reqHeader);

        int totalNum = p_reqBat.getTotalNum();
        if(totalNum != 1) {
            retAts.respCode = "-1";
            retAts.respInfo = "中信银行跨行代扣渠道每批只可以是1笔交易,请在MBS端设置渠道拆分笔数参数值为1";
        } else {
            if(p_reqBat.reqHeader.transType.equals("9188")) {
                StringBuilder reqMessage = new StringBuilder();

                while (p_reqBat.readRecord()) {
                    StringBuilder errmessage = new StringBuilder();
                    requiredCheck(p_reqBat,errmessage);
                    if(errmessage.length() > 0) {
                        retAts.respCode = "-1";
                        retAts.respInfo = errmessage.toString();
                        System.out.println(Format.DateTimeSSSFormat.format(new Date()) + "CITIC42必填校验结果:"+errmessage.toString());
                    } else {
                        //<editor-fold desc="组装报文体body部分">
                        StringBuilder messageBody = new StringBuilder();

                        String busiType = this.getBankConfig().getValueAsString("busiType");
                        String recCnapsCode = this.getBankConfig().getValueAsString("recCnapsCode");
                        Date payDate = p_reqBat.readedDetail.getPayDateOnly();
                        String formatePayDate = Format.Date8Format.format(payDate);
                        String payAct = p_reqBat.readedDetail.payAct;
                        String payName = p_reqBat.readedDetail.payName;
                        String payBankName = p_reqBat.readedDetail.payBankName;
                        String payCnapsCode = p_reqBat.readedDetail.cnapsCode;
                        String cardType = p_reqBat.readedDetail.cvv2;//卡折类型
                        if("2".equals(cardType)) {
                            cardType = "ATO2";
                        } else if("3".equals(cardType)) {
                            cardType = "ATO1";
                        }
                        String payAmount = p_reqBat.readedDetail.payAmount;
                        //String formatAmount = Format.DecimalAmtFormat.format(payAmount);
                        String recAct = p_reqBat.readedDetail.recAct;
                        String recName = p_reqBat.readedDetail.recName;
                        String recBankName = p_reqBat.readedDetail.recBankName;
                        String authAgNum = p_reqBat.readedDetail.authAgNum;//协议号
                        String abstractATS = p_reqBat.readedDetail.abstractATS;
                        String memo = p_reqBat.readedDetail.memo;

                        messageBody.append(formatePayDate).append("|").append(busiType).append("|").append(payAct).append("|").append(payName).append("|");
                        messageBody.append(payBankName).append("|").append(payCnapsCode).append("|").append(cardType).append("|").append(payAmount).append("|");
                        messageBody.append(recAct).append("|").append(recName).append("|").append(recBankName).append("|").append(recCnapsCode).append("|");
                        messageBody.append(authAgNum).append("|").append(abstractATS).append("|").append(memo).append("|");
                        //</editor-fold>

                        //<editor-fold desc="组装报文的头部信息">
                        CITIC42Header header = new CITIC42Header();
                        header.messageFixedHeader = this.getBankConfig().getValueAsString("payMessageFixedHeader");
                        header.messageType = this.getBankConfig().getValueAsString("payMessageType");
                        //流水号值为yyyyMMddHHmmss+6位序号，采用指令发送时间+支付批次号后6位
                        String reqBatchNO = p_reqBat.reqBatchNO;
                        Date payDateTime = p_reqBat.readedDetail.getPayDateTime();
                        header.messageSerialno = Format.DateTime14Format.format(payDateTime) + reqBatchNO.substring(reqBatchNO.length()-6);
                        writeCommonHeader(reqMessage,header);
                        //</editor-fold>
                        reqMessage.append(messageBody);
                        //<editor-fold desc="报文的开头插入报文长度:8位左补0">
                        String messageLengthStr = this.getBankConfig().getValueAsString("messageLengthStr");
                        //String reqLength = StringHelper.valueOf(reqMessage.length() + messageLengthStr.length());
                        String reqLength = StringHelper.valueOf(reqMessage.length());
                        messageLengthStr = messageLengthStr.substring(reqLength.length()) + reqLength;
                        reqMessage.insert(0,messageLengthStr);
                        //</editor-fold>

                        System.out.println(Format.DateTimeSSSFormat.format(new Date()) + "CITIC42扣款报文:"+reqMessage.toString());
                        String[] tmpStrRet = sendToBank(reqMessage.toString());//发送银行
                        if(tmpStrRet[0].length() == 0){
                            if(tmpStrRet.length > 1 && !StringHelper.isNullOrEmpty(tmpStrRet[1])) {
                                StringBuilder tmpSbMsg = new StringBuilder();
                                //解析银行返回 0000004820180413105122122936|1001|11|AAAAAAA|PS11|待组包
                                //String columnStr = "messageSerialno|messageType|commonRespCode|transRespCode|transState|待组包";
                                String valueStr = tmpStrRet[1];
                                System.out.println(Format.DateTimeSSSFormat.format(new Date()) + "CITIC42扣款响应报文:"+valueStr);
                                String[] respArr = valueStr.split("\\|", 1000);
                                //HashMap<String, String> valueMap = SplitHelper.splitAsValueMap(columnStr, valueStr, "\\|",1000);

                                if(respArr != null && respArr.length > 3){
                                    String tmpRetCode = respArr[2];
                                    if(!StringHelper.isNullOrEmpty(tmpRetCode)){
                                        retAts.respCode = OPERATESUCCESS.equals(tmpRetCode) ? "0" : "-1";
                                        if(TRANSRESPONSECODE.equals(respArr[3])) {
                                            retAts.reqSeqID = p_reqBat.reqBatchNO;
                                            retAts.transState = respArr[4];
                                            retAts.payInfoCode = respArr[4];
                                        } else {
                                            retAts.reqSeqID = p_reqBat.reqBatchNO;
                                            retAts.transState = PaymentState.FAIL_Batch;
                                            retAts.payInfoCode = respArr[3];
                                        }
                                    }
                                    else{
                                        retAts.respCode = "-1";
                                        retAts.respInfo = valueStr;
                                        retAts.reqSeqID = p_reqBat.reqBatchNO;
                                    }
                                }
                                else if(tmpStrRet[1].indexOf("Connection refused")>=0){
                                    retAts.respCode = "0";
                                    retAts.respInfo = tmpStrRet[1];
                                    retAts.reqSeqID = p_reqBat.reqBatchNO;
                                    retAts.transState = PaymentState.FAIL_Batch;
                                    retAts.payInfoCode = "E9999";
                                }
                                else{
                                    retAts.respCode = "-1";
                                    retAts.respInfo = tmpSbMsg.toString();
                                    retAts.reqSeqID = p_reqBat.reqBatchNO;
                                }
                            }
                        }
                        else if(tmpStrRet[0].equals(ConnState.FAIL)){
                            retAts.respCode = "0";
                            retAts.respInfo = tmpStrRet[1];
                            retAts.reqSeqID = p_reqBat.reqBatchNO;
                            retAts.transState = PaymentState.FAIL_Batch;
                            retAts.payInfoCode = tmpStrRet[0];
                        }
                        else{
                            retAts.respCode = "-1";
                            retAts.respInfo = tmpStrRet[1];
                            retAts.reqSeqID = p_reqBat.reqBatchNO;
                        }
                    }
                }
            }
        }

        retAts.writeRetToATS();
        return retAts;
    }

    /**
     * 批量代扣结果查询
     * @param p_reqQryBat
     * @return
     * @throws Exception
     */
    public RetAtsQryBatPayRec d_QryBatPayRec(ReqQryBatPayRec p_reqQryBat) throws Exception{
        //返回ATS的对象
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_reqQryBat.reqHeader);

        if(p_reqQryBat.reqHeader.transType.equals("9198")) {
            StringBuilder reqMessage = new StringBuilder();
            StringBuilder messageBody = new StringBuilder();

            String reqBatchNO = p_reqQryBat.reqBatchNO;//p_reqQryBat.reqHeader.reqSeqID;//批次号
            //String payDateTime = p_reqQryBat.bgnDate;
            String payDate = Format.Date8Format.format(Format.DateTimeFormat.parse(p_reqQryBat.bgnDate));//交易日期
            String payMessageType = this.getBankConfig().getValueAsString("payMessageType");
            String busiType = this.getBankConfig().getValueAsString("busiType");

            Date bgnDate = p_reqQryBat.getBgnDateTime();//指令发送时间
            String messageSerialno = Format.DateTime14Format.format(bgnDate) + reqBatchNO.substring(reqBatchNO.length()-6);

            messageBody.append(payDate).append("|").append(payMessageType).append("|").append(busiType).append("|").append(messageSerialno).append("|");

            //<editor-fold desc="组装报文的头部信息">
            CITIC42Header header = new CITIC42Header();
            header.messageFixedHeader = this.getBankConfig().getValueAsString("queryMessageFixedHeader");
            header.messageType = this.getBankConfig().getValueAsString("queryMessageType");
            //流水号值为yyyyMMddHHmmss+6位序号，查询时头部报文的这个流水号没用，只要不重复就行,报文体中的流水号是扣款时的头部流水号
            header.messageSerialno = Format.DateTime17Format.format(new Date()) + reqBatchNO.substring(reqBatchNO.length()-3);
            writeCommonHeader(reqMessage,header);
            //</editor-fold>
            reqMessage.append(messageBody);
            //<editor-fold desc="报文的开头插入报文长度:8位左补0">
            String messageLengthStr = this.getBankConfig().getValueAsString("messageLengthStr");
            //String reqLength = StringHelper.valueOf(reqMessage.length() + messageLengthStr.length());
            String reqLength = StringHelper.valueOf(reqMessage.length());
            messageLengthStr = messageLengthStr.substring(reqLength.length()) + reqLength;
            reqMessage.insert(0,messageLengthStr);
            //</editor-fold>

            System.out.println(Format.DateTimeSSSFormat.format(new Date()) + "CITIC42查询报文:"+reqMessage.toString());
            String[] tmpStrRet = sendToBank(reqMessage.toString());//发送银行
            if(tmpStrRet[0].length() == 0){
                if(tmpStrRet.length > 1 && !StringHelper.isNullOrEmpty(tmpStrRet[1])) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    //解析银行返回 0000007920180413105410429970|2001|11|IBR0028|20180413|1000|test57|20180323153240408970|交易状态码|交易状态说明
                    //消息流水号|消息类型码|应答状态码|交易应答码|原交易日期|原交易码1000|原业务类型|原交易流水号|交易状态码|交易状态说明
                    //String columnStr = "messageSerialno|messageType|commonRespCode|transRespCode|payDate|messageType|busiType|payMessageSerialno|transState|";
                    String valueStr = tmpStrRet[1];
                    System.out.println(Format.DateTimeSSSFormat.format(new Date()) + "CITIC42状态查询响应报文:"+valueStr);
                    String[] respArr = valueStr.split("\\|", 1000);
                    //HashMap<String, String> valueMap = SplitHelper.splitAsValueMap(columnStr, valueStr, "\\|",1000);

                    if(respArr != null && respArr.length > 3){
                        String tmpRetCode = respArr[2];
                        if(!StringHelper.isNullOrEmpty(tmpRetCode)){
                            retAts.respCode = OPERATESUCCESS.equals(tmpRetCode) ? "0" : "-1";
                            if(TRANSRESPONSECODE.equals(respArr[3])) {
                                retAts.transState = respArr[8];
                                retAts.payInfoCode = respArr[8];
                                retAts.reqSeqID = p_reqQryBat.reqBatchNO;
                            } else {
                                retAts.transState = PaymentState.FAIL_Batch;
                                retAts.payInfoCode = respArr[3];
                                retAts.reqSeqID = p_reqQryBat.reqBatchNO;
                            }
                        }
                        else{
                            retAts.respCode = "-1";
                            retAts.respInfo = valueStr;
                            retAts.reqSeqID = p_reqQryBat.reqBatchNO;
                        }
                    }
                    else if(tmpStrRet[1].indexOf("Connection refused")>=0){
                        retAts.respCode = "0";
                        retAts.respInfo = tmpStrRet[1];
                        retAts.reqSeqID = p_reqQryBat.reqBatchNO;
                        retAts.transState = PaymentState.FAIL_Batch;
                        retAts.payInfoCode = "E9999";
                    }
                    else{
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpSbMsg.toString();
                        retAts.reqSeqID = p_reqQryBat.reqBatchNO;
                    }
                }
            }
            else if(tmpStrRet[0].equals(ConnState.FAIL)){
                retAts.respCode = "0";
                retAts.respInfo = tmpStrRet[1];
                retAts.reqSeqID = p_reqQryBat.reqBatchNO;
            }
            else{
                retAts.respCode = "-1";
                retAts.respInfo = tmpStrRet[1];
                retAts.reqSeqID = p_reqQryBat.reqBatchNO;
            }

        }

        retAts.writeAfterDetail();
        return retAts;
    }

    @Override
    public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
        return null;
    }

    @Override
    public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        return null;
    }

    @Override
    public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
        return d_BatPayRec(p_req9188);
    }

    @Override
    public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
        return d_QryBatPayRec(p_req9198);
    }

    /**
     * 必填项校验
     * @param p_reqBat
     * @param messge
     */
    private void requiredCheck(ReqBatPayRec p_reqBat,StringBuilder messge) throws Exception {
        Map<String,Object> values = new HashMap<String, Object>();
        values.put("payDate",p_reqBat.readedDetail.getPayDateOnly());
        values.put("payAct",p_reqBat.readedDetail.payAct);
        values.put("payName",p_reqBat.readedDetail.payName);
        values.put("payBankName",p_reqBat.readedDetail.payBankName);
        values.put("cnapsCode",p_reqBat.readedDetail.cnapsCode);
        values.put("creditCardSecCode",p_reqBat.readedDetail.cvv2);
        values.put("payAmount",p_reqBat.readedDetail.payAmount);
        values.put("recAct",p_reqBat.readedDetail.recAct);
        values.put("recName",p_reqBat.readedDetail.recName);
        values.put("recBankName",p_reqBat.readedDetail.recBankName);
        values.put("authAgNum",p_reqBat.readedDetail.authAgNum);
        //values.put("abstractATS",p_reqBat.readedDetail.abstractATS);
        //values.put("memo",p_reqBat.readedDetail.memo);

        for (String key : values.keySet()) {
            if(StringHelper.isNullOrEmpty(StringHelper.valueOf(values.get(key)))) {
                messge.append(key + "不能为空");
            }
        }
    }
}
